package net.midnighttd.engine.view.sprite;

import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import java.util.*;
import java.awt.*;
import java.awt.geom.AffineTransform;

/**
 * Author: Adam Scarr
 * Date: 19/04/2009
 * Time: 12:28:36 PM
 * A sprite is a collection of animations played at a set speed depending on state.
 */
public class XMLSprite extends Sprite implements Comparable {
    private HashMap<String, Animation> states;
    private String state;

    /**
     * Makes a copy of a sprite, only recreating the appropriate data.
     * Animations are shared between all copys of a sprite, but location and
     * rotation, as well as movement queues are kept seperate.
     * @param copy The Sprite you are copying from.
     */
    protected XMLSprite(Sprite copy) {
        super(copy);
        if(copy instanceof XMLSprite) {
            this.states = ((XMLSprite)copy).states;
            this.state = ((XMLSprite)copy).state;
        }
    }

    public XMLSprite(Element xmlSpriteElement) {
        super(xmlSpriteElement.getAttribute("name"), 
              Integer.valueOf(xmlSpriteElement.getAttribute("width")),
              Integer.valueOf(xmlSpriteElement.getAttribute("height")),
              xmlSpriteElement.getAttribute("z-order").equals("") ? 0 : Integer.valueOf(xmlSpriteElement.getAttribute("z-order")));
        states = new HashMap<String, Animation>();
        state = xmlSpriteElement.getAttribute("default");
        readAnimations(xmlSpriteElement.getElementsByTagName("animation"));
    }

    private void readAnimations(NodeList animations) {
        for(int i = 0; i < animations.getLength(); i++) {
            Element animation = (Element)animations.item(i);
            String aniName = animation.getAttribute("name");
            String filename = animation.getAttribute("filename");
            int index = Integer.valueOf(animation.getAttribute("index"));
            int frames = Integer.valueOf(animation.getAttribute("frames"));
            int fps = Integer.valueOf(animation.getAttribute("fps"));
            String playnext = animation.getAttribute("playnext");
            Animation newAnimation = new Animation(aniName, filename, index, frames, fps, getWidth(), getHeight(), playnext);
            states.put(aniName, newAnimation);
        }
    }

    public void draw(Graphics g) {
        Animation curAnim = states.get(state);
        if(curAnim == null) {
            System.out.println("Could not find state " + state + " for sprite " + getName() );
        }
        Image frame = curAnim.getFrame();
        if(frame == null) {
            state = curAnim.getNextState();
            
            curAnim = states.get(state);
            if(curAnim == null) {
                System.out.println("Could not find state " + state + " for sprite " + getName() );
            }
            frame = curAnim.getFrame();
        }
        int frameWidth = frame.getWidth(null);
        int frameHeight = frame.getHeight(null);

        Graphics2D g2d = (Graphics2D)g;

        AffineTransform affineTransform = new AffineTransform();
        affineTransform.setToTranslation(getX(), getY());
        affineTransform.rotate(getRotation(), frameWidth / 2, frameHeight / 2);
        g2d.drawImage(frame, affineTransform, null);
    }

    public long toDuration(double degrees, double speed) {
        return (long)((degrees / speed) * 1000000000); 
    }



    public void setState(String state) {
        this.state = state;
        states.get(state).rewind();
    }

    public Animation getAnimation(String state) {
        return states.get(state);
    }

    public Sprite copy() {
        return new XMLSprite(this);
    }
}
